/****************************************************************************
**
** Copyright (C) 2011 Jesús Martínez Pérez
**
** This program is free software: you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the 
** Free Software Foundation, either version 3 of the License, or (at your
** option) any later version.
**
** This program is distributed in the hope that it will be useful, but 
** WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License along 
** with this program. If not, see <http://www.gnu.org/licenses/>
**
****************************************************************************/
#include <fstream>
#include <deflate.h>
#include <iostream>
using namespace std;

int main(int argc, char * argv[]){
	int tamnombre=0;
	char * nombre;
	if((argc==2)||(argc==3)){
		if(argc==2){
			for(int i=0; argv[1][i]!='\0'; i++){
				tamnombre++;   
			}
			nombre=new char[tamnombre+4];
			int i;
			for(i=0; argv[1][i]!='\0'; i++){
				nombre[i]=argv[1][i];  
			}
			char ext[]=".gz";
			for(int j=0;j<3;j++){
				nombre[i]=ext[j];
				i++;
			}
		}
		if(argc==3){
			for(int i=0; argv[2][i]!='\0'; i++){
				tamnombre++;   
			}
			nombre=new char[tamnombre];
			int i;
			for(i=0; argv[2][i]!='\0'; i++){
				nombre[i]=argv[2][i];  
			}
		}
	}
	else{
		cerr<<"Sintaxis incorrecta, pruebe con './bin/mp2gzip <fichero original>' o con './bin/ mp2gzip <fichero original> [<fichero destino comprimido> ]'"<<endl;
		return 1;
	}
//abrimos el archivo a comprimir
	fstream f(argv[1],ios::in);
	if(!f){
		cerr<<"No se ha podido abrir "<<argv[1]<<endl;
		return 1;
	}
	Deflate d;
//pasamos el archivo abierto a deflate
	f>>d;
//codificación lz77
	d.CodLZ();
//Deflate
	d.CodDeflate();
	//cout<<d;
//creamos el archivo de destino
	fstream fo(nombre,ios::binary|ios::out);
	if(!fo){
		cerr<<"No se ha podido crear el archivo de destino "<<argv[2]<<endl;
		return 1;
	}

	unsigned char id=31;
	unsigned char id2=139;
	unsigned char cm=8;
	unsigned char flg=24;
	unsigned char xfl=4;
	unsigned char os=255;
	unsigned int mtim=0;
	int tamargv1=0;
	for(int i=0; argv[1][i]!='\0'; i++){
			tamargv1++;   
	}
	char nombredni[]="Datos Nombre y DNI del alumno.";
	int tamnd=30;
	unsigned int crc32=d.CRC32();
	unsigned int tama=(unsigned int)d.tamano();
	
//cabecera en el archivo de destino
	fo.write(reinterpret_cast<const char *>(&id), sizeof(unsigned char));
	fo.write(reinterpret_cast<const char *>(&id2), sizeof(unsigned char));
	fo.write(reinterpret_cast<const char *>(&cm), sizeof(unsigned char));
	fo.write(reinterpret_cast<const char *>(&flg), sizeof(unsigned char));
	fo.write(reinterpret_cast<const char *>(&mtim), sizeof(unsigned int));
	fo.write(reinterpret_cast<const char *>(&xfl), sizeof(unsigned char));
	fo.write(reinterpret_cast<const char *>(&os), sizeof(unsigned char));
//nombre del archivo 
	fo.write(reinterpret_cast<const char *>(argv[1]),(tamargv1+1));
//nombre y dni
	fo.write(reinterpret_cast<const char *>(nombredni),(tamnd+1));
//salida del deflate 
	for(int i=0;i<d.Size()/8;i++){
		unsigned char defb=d.GetB(i);
		fo.write(reinterpret_cast<const char *>(&defb),sizeof(unsigned char));
	}
//CRC32
	fo.write(reinterpret_cast<const char *>(&crc32),sizeof(unsigned int));
//tamaño que ocupa
	fo.write(reinterpret_cast<const char *>(&tama),sizeof(unsigned int));
}


